#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import flujo_entrada
from catlex import *
import string

def _rango(a, z): # función auxiliar
    return map(chr, range(ord(a), ord(z) + 1))

class analizador_lexico:
    def __init__(self, entrada):
        # Tabla de transiciones
        self.d = {}
        
        # estado 1
        self.d[1, ""] = 2
        for c in _rango('a', 'z'):
            self.d[1, c] = 3
        for c in _rango('0', '9'):
            self.d[1, c] = 4
        self.d[1, ":"] = 6
        for c in [" ", "\t", "\n"]:
            self.d[1, c] = 8
        
        # estado 3
        for c in _rango('a', 'z'):
            self.d[3, c] = 3
        for c in _rango('0', '9'):
            self.d[3, c] = 3
        
        # estado 4
        for c in _rango('0', '9'):
            self.d[4, c] = 4
        self.d[4, "."] = 5
        
        # estado 5
        for c in _rango('0', '9'):
            self.d[5, c] = 5
            
        # estado 6
        self.d[6, "="] = 7
        
        # estado 8
        for c in [" ", "\t", "\n"]:
            self.d[8, c] = 8
            
        # Tabla de estados finales
        self.finales = [2, 3, 4, 5, 7, 8]
        
        # Tabla de acciones
        self.accion = {
                       2 : self._emitir_eof,
                       3 : self._emitir_identificador,
                       4 : self._emitir_entero,
                       5 : self._emitir_real,
                       7 : self._emitir_asignacion,
                       }
        
        # Inicialización del analizador
        self.entrada = entrada
        self.comp = None
        self.avanza()
        
    def avanza(self):
        c = self.entrada.siguiente_caracter()
        self.estado = 1
        self.lexema = ""
        while 1:
#            if self.d.has_key(self.estado, c):
            if self.d.has_key(self.estado):
                self.estado = self.d[self.estado, c]
                self.lexema = self.lexema + c
                self.entrada.avanza()
                c = self.entrada.siguiente_caracter()
            else:
                if self.estado in self.finales:
                    if self.estado in self.accion.keys():
                        self.accion[self.estado]()
                        break
                    else:
                        self.estado = 1
                        self.lexema = ""
                else:
                    print self.d.has_key(self.estado)
                    raise "ERROR" # -> tratamiento de error
    
    def siguiente_componente(self):
        return self.comp
    
    def _emitir_eof(self):
        self.comp = eof()
        
    def _emitir_identificador(self):
        self.comp = identificador(self.lexema)
        
    def _emitir_entero(self):
        self.comp = entero(string.atoi(self.lexema))
        
    def _emitir_real(self):
        self.comp = real(string.atof(self.lexema))
        
    def _emitir_asignacion(self):
        self.comp = asignacion()
        
if __name__ == "__main__":
    fe = flujo_entrada.cadena("ab := 4 abc10 2.100")
    a = analizador_lexico(fe)
    while a.siguiente_componente().cat != cat.eof:
        print a.siguiente_componente()
        a.avanza()
        
        